{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9fc56b34-7835-4a06-87fb-7dde601bc7ac",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-11-19 12:41:43.012224: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:975] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n",
      "2024-11-19 12:41:43.015920: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.016089: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.016189: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.016290: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcufft.so.10'; dlerror: libcufft.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.511213: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.511350: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:43.511360: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n",
      "Skipping registering GPU devices...\n",
      "2024-11-19 12:41:43.511887: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F AVX512_VNNI FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "58889256/58889256 [==============================] - 0s 0us/step\n",
      "Model: \"model\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " input_2 (InputLayer)        [(None, 224, 224, 3)]     0         \n",
      "                                                                 \n",
      " vgg16 (Functional)          (None, 7, 7, 512)         14714688  \n",
      "                                                                 \n",
      " global_average_pooling2d (G  (None, 512)              0         \n",
      " lobalAveragePooling2D)                                          \n",
      "                                                                 \n",
      " dense (Dense)               (None, 6)                 3078      \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 14,717,766\n",
      "Trainable params: 3,078\n",
      "Non-trainable params: 14,714,688\n",
      "_________________________________________________________________\n",
      "Found 1182 images belonging to 6 classes.\n",
      "Found 329 images belonging to 6 classes.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/dist-packages/keras/preprocessing/image.py:1663: UserWarning: This ImageDataGenerator specifies `featurewise_center`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.\n",
      "  warnings.warn('This ImageDataGenerator specifies '\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "36/36 [==============================] - 173s 5s/step - loss: 2.1959 - accuracy: 0.5008 - val_loss: 0.9776 - val_accuracy: 0.7112\n",
      "Epoch 2/10\n",
      "36/36 [==============================] - 169s 5s/step - loss: 0.6720 - accuracy: 0.7986 - val_loss: 0.4575 - val_accuracy: 0.8450\n",
      "Epoch 3/10\n",
      "36/36 [==============================] - 163s 4s/step - loss: 0.3693 - accuracy: 0.8756 - val_loss: 0.3539 - val_accuracy: 0.8845\n",
      "Epoch 4/10\n",
      "36/36 [==============================] - 169s 5s/step - loss: 0.2341 - accuracy: 0.9196 - val_loss: 0.2890 - val_accuracy: 0.9058\n",
      "Epoch 5/10\n",
      "36/36 [==============================] - 162s 4s/step - loss: 0.1803 - accuracy: 0.9281 - val_loss: 0.2395 - val_accuracy: 0.9271\n",
      "Epoch 6/10\n",
      "36/36 [==============================] - 153s 4s/step - loss: 0.1498 - accuracy: 0.9475 - val_loss: 0.2318 - val_accuracy: 0.9362\n",
      "Epoch 7/10\n",
      "36/36 [==============================] - 153s 4s/step - loss: 0.1150 - accuracy: 0.9645 - val_loss: 0.2126 - val_accuracy: 0.9453\n",
      "Epoch 8/10\n",
      "36/36 [==============================] - 172s 5s/step - loss: 0.1193 - accuracy: 0.9552 - val_loss: 0.1845 - val_accuracy: 0.9453\n",
      "Epoch 9/10\n",
      "36/36 [==============================] - 166s 5s/step - loss: 0.0894 - accuracy: 0.9662 - val_loss: 0.1979 - val_accuracy: 0.9453\n",
      "Epoch 10/10\n",
      "36/36 [==============================] - 169s 5s/step - loss: 0.0913 - accuracy: 0.9636 - val_loss: 0.1962 - val_accuracy: 0.9453\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name '不需要解冻微调' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[2], line 79\u001b[0m\n\u001b[1;32m     64\u001b[0m valid_it \u001b[38;5;241m=\u001b[39m datagen\u001b[38;5;241m.\u001b[39mflow_from_directory(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdata/fruits/valid\u001b[39m\u001b[38;5;124m\"\u001b[39m, \n\u001b[1;32m     65\u001b[0m                                       target_size\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m224\u001b[39m, \u001b[38;5;241m224\u001b[39m), \n\u001b[1;32m     66\u001b[0m                                       color_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrgb\u001b[39m\u001b[38;5;124m'\u001b[39m, \n\u001b[1;32m     67\u001b[0m                                       class_mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcategorical\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m     71\u001b[0m model\u001b[38;5;241m.\u001b[39mfit(train_it,\n\u001b[1;32m     72\u001b[0m           validation_data\u001b[38;5;241m=\u001b[39mvalid_it,\n\u001b[1;32m     73\u001b[0m           steps_per_epoch\u001b[38;5;241m=\u001b[39mtrain_it\u001b[38;5;241m.\u001b[39msamples\u001b[38;5;241m/\u001b[39mtrain_it\u001b[38;5;241m.\u001b[39mbatch_size,\n\u001b[1;32m     74\u001b[0m           validation_steps\u001b[38;5;241m=\u001b[39mvalid_it\u001b[38;5;241m.\u001b[39msamples\u001b[38;5;241m/\u001b[39mvalid_it\u001b[38;5;241m.\u001b[39mbatch_size,\n\u001b[1;32m     75\u001b[0m           epochs\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m10\u001b[39m)\n\u001b[0;32m---> 79\u001b[0m \u001b[43m不需要解冻微调\u001b[49m\n\u001b[1;32m     83\u001b[0m 后面依次运行\n",
      "\u001b[0;31mNameError\u001b[0m: name '不需要解冻微调' is not defined"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "sys.setrecursionlimit(10000)  # 将递归深度限制设置为10000\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "base_model = keras.applications.VGG16(\n",
    "    weights=\"imagenet\",\n",
    "    input_shape=(224, 224, 3),\n",
    "    include_top=False)\n",
    "\n",
    "\n",
    "\n",
    "# Freeze base model\n",
    "base_model.trainable = False\n",
    "\n",
    "\n",
    "\n",
    "# Create inputs with correct shape\n",
    "inputs = keras.Input(shape=(224, 224, 3))\n",
    "\n",
    "x = base_model(inputs, training=False)\n",
    "\n",
    "# Add pooling layer or flatten layer\n",
    "x = keras.layers.GlobalAveragePooling2D()(x)\n",
    "\n",
    "# Add final dense layer\n",
    "outputs = keras.layers.Dense(6, activation = 'softmax')(x)\n",
    "\n",
    "# Combine inputs and outputs to create model\n",
    "model = keras.Model(inputs, outputs)\n",
    "\n",
    "\n",
    "\n",
    "model.summary()\n",
    "\n",
    "\n",
    "\n",
    "model.compile(loss='categorical_crossentropy', optimizer='adam',  metrics=['accuracy'])\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "# create a data generator\n",
    "datagen = ImageDataGenerator(\n",
    "        featurewise_center=True,  # set input mean to 0 over the dataset\n",
    "        samplewise_center=True,  # set each sample mean to 0\n",
    "        rotation_range=10,  # randomly rotate images in the range (degrees, 0 to 180)\n",
    "        zoom_range = 0.1, # Randomly zoom image \n",
    "        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)\n",
    "        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)\n",
    "        horizontal_flip=True,  # randomly flip images\n",
    "        vertical_flip=False) # we don't expect Bo to be upside-down so we will not flip vertically\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# load and iterate training dataset\n",
    "train_it = datagen.flow_from_directory(\"data/fruits/train\", \n",
    "                                       target_size=(224, 224), \n",
    "                                       color_mode='rgb', \n",
    "                                       class_mode=\"categorical\")\n",
    "# load and iterate validation dataset\n",
    "valid_it = datagen.flow_from_directory(\"data/fruits/valid\", \n",
    "                                      target_size=(224, 224), \n",
    "                                      color_mode='rgb', \n",
    "                                      class_mode=\"categorical\")\n",
    "\n",
    "\n",
    "\n",
    "model.fit(train_it,\n",
    "          validation_data=valid_it,\n",
    "          steps_per_epoch=train_it.samples/train_it.batch_size,\n",
    "          validation_steps=valid_it.samples/valid_it.batch_size,\n",
    "          epochs=10)\n",
    "\n",
    "\n",
    "\n",
    "不需要解冻微调\n",
    "\n",
    "\n",
    "\n",
    "后面依次运行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "368e5252-b88f-4bca-a60b-fe378efb2ebf",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.save('my_model.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "31d03d24-ba3d-4969-800a-fa2a876b4493",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-11-19 12:41:26.795521: I tensorflow/core/util/util.cc:169] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
      "2024-11-19 12:41:26.800479: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/compat/lib.real:/usr/local/lib/python3.10/dist-packages/torch/lib:/usr/local/lib/python3.10/dist-packages/torch_tensorrt/lib:/usr/local/cuda/compat/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64\n",
      "2024-11-19 12:41:26.800496: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.9.1\n",
      "2.9.0\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "sys.setrecursionlimit(10000)  # 将递归深度限制设置为10000\n",
    "\n",
    "import tensorflow as tf\n",
    "print(tf.__version__)\n",
    "print(tf.keras.__version__)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "309f233b-efea-42a0-8151-82310d3034e9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://pypi.org/simple, https://pypi.ngc.nvidia.com\n",
      "Collecting numpy==1.24.3\n",
      "  Downloading numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.6 kB)\n",
      "Downloading numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.3 MB)\n",
      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m17.3/17.3 MB\u001b[0m \u001b[31m226.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
      "\u001b[?25hInstalling collected packages: numpy\n",
      "  Attempting uninstall: numpy\n",
      "    Found existing installation: numpy 1.26.4\n",
      "    Uninstalling numpy-1.26.4:\n",
      "      Successfully uninstalled numpy-1.26.4\n",
      "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
      "cudf 24.2.0 requires pandas<1.6.0dev0,>=1.3, but you have pandas 2.2.3 which is incompatible.\n",
      "cudf 24.2.0 requires protobuf<5,>=4.21, but you have protobuf 3.19.6 which is incompatible.\n",
      "dask-cuda 24.2.0 requires pandas<1.6.0.dev0,>=1.3, but you have pandas 2.2.3 which is incompatible.\n",
      "dask-cudf 24.2.0 requires pandas<1.6.0dev0,>=1.3, but you have pandas 2.2.3 which is incompatible.\n",
      "onnx 1.16.0 requires protobuf>=3.20.2, but you have protobuf 3.19.6 which is incompatible.\n",
      "torchtext 0.17.0a0 requires torch==2.3.0a0+6ddf5cf, but you have torch 2.3.0a0+6ddf5cf85e.nv24.4 which is incompatible.\u001b[0m\u001b[31m\n",
      "\u001b[0mSuccessfully installed numpy-1.24.3\n",
      "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n",
      "\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m24.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.3.1\u001b[0m\n",
      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpython -m pip install --upgrade pip\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "# # pip install tensorflow\n",
    "# !pip install numpy==1.26.4\n",
    "# !pip list --outdated\n",
    "# !pip install --upgrade <package_name>\n",
    "# !pip install pandas --upgrade\n",
    "# !pip install tensorflow==2.9.1\n",
    "# !pip install keras==2.9.0\n",
    "!pip install numpy==1.24.3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "dc5329a8-cc46-4599-92de-e2cd525dc0d8",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'valid_loader' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[8], line 13\u001b[0m\n\u001b[1;32m     11\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mutils\u001b[39;00m\n\u001b[1;32m     12\u001b[0m \u001b[38;5;66;03m# utils.validate(my_model, valid_loader, valid_N, loss_function)\u001b[39;00m\n\u001b[0;32m---> 13\u001b[0m utils\u001b[38;5;241m.\u001b[39mvalidate(model, \u001b[43mvalid_loader\u001b[49m, valid_N, loss_function)\n",
      "\u001b[0;31mNameError\u001b[0m: name 'valid_loader' is not defined"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.optim import Adam\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "import torchvision.transforms.v2 as transforms\n",
    "import torchvision.io as tv_io\n",
    "\n",
    "import glob\n",
    "from PIL import Image\n",
    "\n",
    "import utils\n",
    "# utils.validate(my_model, valid_loader, valid_N, loss_function)\n",
    "utils.validate(model, valid_loader, valid_N, loss_function)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "54b7ae8e-aefa-4222-95d9-bb57760e44bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "from run_assessment import run_assessment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "4a933397-4300-4320-9c38-2a308a37567a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Evaluating model to obtain average accuracy...\n",
      "\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'Functional' object has no attribute 'eval'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[13], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mrun_assessment\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m/dli/assessment/notebook_helpers/run_assessment.py:63\u001b[0m, in \u001b[0;36mrun_assessment\u001b[0;34m(model)\u001b[0m\n\u001b[1;32m     61\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrun_assessment\u001b[39m(model):\n\u001b[1;32m     62\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mEvaluating model to obtain average accuracy...\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m---> 63\u001b[0m     average \u001b[38;5;241m=\u001b[39m \u001b[43mvalidate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m     64\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mAccuracy required to pass the assessment is 0.92 or greater.\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m     65\u001b[0m     \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mYour average accuracy is \u001b[39m\u001b[38;5;132;01m{:5.4f}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mformat(average))\n",
      "File \u001b[0;32m/dli/assessment/notebook_helpers/run_assessment.py:53\u001b[0m, in \u001b[0;36mvalidate\u001b[0;34m(model)\u001b[0m\n\u001b[1;32m     50\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mvalidate\u001b[39m(model):\n\u001b[1;32m     51\u001b[0m     accuracy \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m---> 53\u001b[0m     \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43meval\u001b[49m()\n\u001b[1;32m     54\u001b[0m     \u001b[38;5;28;01mwith\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mno_grad():\n\u001b[1;32m     55\u001b[0m         \u001b[38;5;28;01mfor\u001b[39;00m x, y \u001b[38;5;129;01min\u001b[39;00m valid_loader:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'Functional' object has no attribute 'eval'"
     ]
    }
   ],
   "source": [
    "run_assessment(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf921e01-8356-4c01-830d-0b6e4ff2eeec",
   "metadata": {},
   "source": [
    "评估模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "b8b571cc-1b6b-4241-a4f2-dde7731d132f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found 329 images belonging to 6 classes.\n",
      "11/11 [==============================] - 36s 3s/step - loss: 0.4142 - accuracy: 0.8602\n",
      "Validation loss: 0.41422969102859497\n",
      "Validation accuracy: 0.8601823449134827\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.keras.models import load_model\n",
    "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
    "\n",
    "# 加载模型\n",
    "model = load_model('my_model.h5')\n",
    "\n",
    "# 创建数据生成器\n",
    "datagen = ImageDataGenerator()\n",
    "\n",
    "# 加载验证数据集\n",
    "valid_it = datagen.flow_from_directory(\"data/fruits/valid\", \n",
    "                                       target_size=(224, 224), \n",
    "                                       color_mode='rgb', \n",
    "                                       class_mode=\"categorical\")\n",
    "\n",
    "# 评估模型\n",
    "loss, accuracy = model.evaluate(valid_it)\n",
    "print(f'Validation loss: {loss}')\n",
    "print(f'Validation accuracy: {accuracy}')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53f8d2e4-4807-431c-9e79-61fbaf6aea5d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
